#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
void attack_wifi2g(int channel);
int read_channel();
void  dispatch_ServerMsg(char* recvbufFromSer);
void send_sig_to_windows();
void enter_ap_mode();


#define MAX_LEN 1000
#define SSIDLEN  100


typedef struct
{
 char ssid[SSIDLEN];
 int channel;
 int command;//1:重启完毕开始干扰，具体SSID见ssid[]，2：重启完毕进入抓包模式
}command;


int sendbuf[MAX_LEN];
int sk;
char buf[MAX_LEN];
struct sockaddr_in ser_addr;								//是用于指定对方(目的主机)信息
struct sockaddr_in loc_addr;								//可以用来指定一些本地的信息，比如指定端口进行通信，而不是让系统随机分配
int ser_addr_len,loc_addr_len;

int main()
{	
	enter_ap_mode();
	int ch = read_channel();
	attack_wifi2g(ch); //attack!!!  
	

    int ret =0,count = 0;

    //配置服务器信息
    bzero(&ser_addr, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;                                //设置为IPV4通信
    ser_addr.sin_addr.s_addr = inet_addr("192.168.0.101");       //设置目的ip
    ser_addr.sin_port = htons(5051);           	 				 //设置目的端口去链接服务器
    ser_addr_len = sizeof(ser_addr);


	//配置本地信息
    bzero(&loc_addr, sizeof(loc_addr));
    loc_addr.sin_family = AF_INET;                                //设置为IPV4通信
    loc_addr.sin_addr.s_addr = htonl(INADDR_ANY);                 //设置目的ip
    loc_addr.sin_port = htons(5051);                              //设置本地端口去链接服务器
    loc_addr_len = sizeof(loc_addr);

    sk = socket(AF_INET, SOCK_DGRAM, 0);                          //设置UDP报文传输    0表示默认    SOCK_DGRAM 默认使用UDP
    if(sk<0){
        printf("socket create failure\n");
        return -1;
    }
    ret = bind(sk,(struct sockaddr*)&loc_addr,loc_addr_len);
    if(ret < 0) {
        printf("socket bind failure\n");
        return -1;
    }
	
	send_sig_to_windows();
    for (;;){
        count = recvfrom(sk,buf,sizeof(buf),0,NULL,NULL);
        if (count==-1)
        {
            printf("receive data failure\n");
            return -1;
        }
		else{
		printf("Command Receive\n");
		sleep(5);
		dispatch_ServerMsg(buf);
		}
    }
    printf("communicate end\n");
    close(sk);
    return 0;

}

void attack_wifi2g(int channel)
{
	char shell[200] = "";
	if( 1<=channel && channel<=13){
		system("rmmod /lib/modules/4.1.51/extra/dhd.ko");
		sleep(3);
		system("insmod /lib/modules/4.1.51/extra/dhd.ko  nvram_path=/DHD/iptime_11ax_2g_nvram.txt");
		sprintf(shell,"/DHD/test_2g_eth6_tx.sh %d 3 20 7 0 &",channel);
	}
	else if(36<=channel && channel <= 165){
		system("rmmod /lib/modules/4.1.51/extra/dhd.ko");
		sleep(3);
		system("insmod /lib/modules/4.1.51/extra/dhd.ko  nvram_path=/DHD/iptime_11ax_5g_nvram.txt");
		sprintf(shell,"/DHD/test_5g_eth5_tx.sh %d 3 20 7 0 &",channel);
	}
	system(shell);
}


void  dispatch_ServerMsg(char* recvbufFromSer) 
{
	/* 1: attack
	   2. capture
	   3. stop capture
	   5. capture

	*/
	int i = 0;
	int channel = 0;
    char *p = recvbufFromSer;
	command *pp = (command *)p;
	if(pp->command == 3){/* stop attack*/
		printf("Stop attack!!\n");
		system("rmmod /lib/modules/4.1.51/extra/dhd.ko");
		
	}
	else if(pp->command == 1){  /* begin attack other channel */
		printf("Begin attack channel %d !!\n",pp->channel);
		channel = pp->channel;
		attack_wifi2g(channel);
	}
	else if(pp->command == 2){  /*  stop attack and begin capture */
			printf("Command : 2 Success\n");
			system("rm /etc/rc3.d/S91attack.sh");
			system("cp /DHD/S90cap.sh  /etc/rc3.d/S90cap.sh");
			system("chmod 777 /etc/rc3.d/S90cap.sh");
			system("reboot");
			
	}
	else if(pp->command == 5){ /*  stop attack and begin capture */
			printf("Command : 5 Success\n");
			system("rm /etc/rc3.d/S91attack.sh");
			system("cp /DHD/S90cap.sh  /etc/rc3.d/S90cap.sh");
			system("chmod 777 /etc/rc3.d/S90cap.sh");
			system("reboot");
		
	}
}

int read_channel()
{
	FILE *fp = NULL;
	int ch = 9;
	char data[400] = "";
	fp = fopen("/DHD/Channel.txt","r");
	fgets(data, sizeof(data), fp);
	ch = atoi(data);
	printf("Get channel : %d\n",ch);
	return ch;
}

void send_sig_to_windows()
{
	command sig;
	sig.command =1;
	memcpy(sendbuf,(char *)&sig,sizeof(command));
	if(sendto(sk,sendbuf,sizeof(sendbuf),0,(struct sockaddr*)&ser_addr, ser_addr_len) != -1){
		printf("Send signal begin attack success\n");
	}
}

void enter_ap_mode()
{
	system("nvram set wl1_mode=ap");
	system("nvram set wl0_mode=ap");
	system("nvram commit");
	sleep(2);
	system("/DHD/sys-restart");
	sleep(25);
	system("nvram show  | grep  _mode");
	
}

